/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simplemetrosystem.view.table;

import java.awt.Component;
import java.util.Observable;
import java.util.Observer;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import simplemetrosystem.control.EditCommandManager;
import simplemetrosystem.control.ElementManager;
import simplemetrosystem.model.Element.MetroEdge;
import simplemetrosystem.model.Element.MetroLine;
import simplemetrosystem.model.charlanguage.NameMap;
import simplemetrosystem.view.InformationPane;
import simplemetrosystem.view.table.Exceptions.InformationPanelException;

/**
 * 
 * 全体关联表格类，
 * @author Eric Qian
 */
public class AllEdgeTable extends JTable implements Observer {

    /**
     * 
     * @param infPane 
     */
    public AllEdgeTable(InformationPane infPane) {
        super();
        this.infPane = infPane;
        elementManager = ElementManager.getInstance();
        elementManager.addObserver(this);
        allEdgeModel = new AllEdgeModel();
        this.setModel(allEdgeModel);
        setRowSelectionAllowed(false);
        setAutoResizeMode(AllLineTable.AUTO_RESIZE_OFF);
        getTableHeader().setReorderingAllowed(false);
        getTableHeader().setResizingAllowed(false);

        setCell();

        setRowHeight(ROW_HEI);

        for (int i = 0; i < getColumnCount(); i++) {
            int with = getPreferredWidthForCloumn(this, i) + 10;
            with = MIN_WIDTH > with ? MIN_WIDTH : with;
            this.getColumnModel().getColumn(i).setPreferredWidth(with);
        }
    }

    private void setCell() {
        TableColumn lineColumn = columnModel.getColumn(AllEdgeModel.COL_LINE);
        lineColumn.setCellEditor(new DefaultCellEditor(getLineBox()));
        TableColumn numColumn = columnModel.getColumn(AllEdgeModel.COL_NUM);
        numColumn.setCellEditor(new AllEdgeNumCellEditor(infPane));
    //ListSelectionModel rowSM = getSelectionModel();
    //rowSM.addListSelectionListener(new EdgeListSelectionListener(infPane));
    }

    private int getPreferredWidthForCloumn(JTable table, int icol) {

        TableColumnModel tcl = table.getColumnModel();
        TableColumn col = tcl.getColumn(icol);
        int c = col.getModelIndex();
        int width = 0;
        int maxw = 0;

        for (int r = 0; r < table.getRowCount(); ++r) {
            TableCellRenderer renderer = table.getCellRenderer(r, c);
            Component comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, c), false, false, r, c);
            width = comp.getPreferredSize().width;
            maxw = width > maxw ? width : maxw;
        }
        return maxw < MAX_WIDTH ? maxw : MAX_WIDTH;
    }

    private JComboBox getLineBox() {
        if (lineBox == null) {
            lineBox = new JComboBox();
            for (int i = 0; i < elementManager.getLinesSize(); i++) {
                lineBox.addItem(elementManager.getLineAt(i).getDisplayName());
            }
        }
        return lineBox;
    }

    public void update(Observable o, Object arg) {
        if (o instanceof ElementManager) {
            lineBox.removeAllItems();
            for (int i = 0; i < elementManager.getLinesSize(); i++) {
                lineBox.addItem(elementManager.getLineAt(i).getDisplayName());
            }
        }
    }
    private InformationPane infPane;
    private ElementManager elementManager;
    private AllEdgeModel allEdgeModel;
    private JComboBox lineBox;
    private static final int MIN_WIDTH = 75;
    private static final int MAX_WIDTH = 125;
    private static final int ROW_HEI = 50;
}
/*
 * 
 */

class AllEdgeModel extends AbstractTableModel {

    /**
     * 
     * @param frame
     * @param elementManager
     */
    public AllEdgeModel() {
        elementManager = ElementManager.getInstance();
        nameMap = NameMap.getInstance();
        editCommandManager = EditCommandManager.getInstance();
        String[] tColumn = {"", nameMap.getName("Station A"), nameMap.getName("Station B"),
            nameMap.getName("Line Name"), nameMap.getName("Serial Number"),
            nameMap.getName("Edge Status"), nameMap.getName("Distance(km)"),
            nameMap.getName("Time(min)")
        };
        columnNames = tColumn;
    }

    public int getRowCount() {
        return elementManager.getEdgesSize();
    }

    @Override
    public String getColumnName(
            int column) {
        return columnNames[column];
    }

    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if (columnIndex == COL_NUM || columnIndex == COL_LINE ||
                columnIndex == COL_SER || columnIndex == COL_DIS || columnIndex == COL_TIM) {
            return true;
        }
        return false;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        if (columnIndex == COL_LINE) {
            if (aValue != null) {
                MetroLine aLine = elementManager.findLine((String) aValue);
                MetroEdge aEdge = elementManager.getEdgeAt(rowIndex);
                editCommandManager.EditEdge(aEdge, aLine,
                        aEdge.getSerialNumber(), aEdge.getDistance(), aEdge.getTime());
            }
        } else if (columnIndex == COL_SER) {
            MetroEdge aEdge = elementManager.getEdgeAt(rowIndex);
            editCommandManager.EditEdge(aEdge, aEdge.getLine(),
                    Integer.parseInt((String) aValue), aEdge.getDistance(), aEdge.getTime());
        } else if (columnIndex == COL_DIS) {
            MetroEdge aEdge = elementManager.getEdgeAt(rowIndex);
            editCommandManager.EditEdge(aEdge, aEdge.getLine(), aEdge.getSerialNumber(),
                    Double.parseDouble((String) aValue), aEdge.getTime());
        } else if (columnIndex == COL_TIM) {
            MetroEdge aEdge = elementManager.getEdgeAt(rowIndex);
            editCommandManager.EditEdge(aEdge, aEdge.getLine(), aEdge.getSerialNumber(),
                    aEdge.getDistance(), Double.parseDouble((String) aValue));
        }
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        if (columnIndex == COL_NUM) {
            return rowIndex + 1;
        } else if (columnIndex == COL_STA) {
            return elementManager.getEdgeAt(rowIndex).getStationA().getDisplayName();
        } else if (columnIndex == COL_STB) {
            return elementManager.getEdgeAt(rowIndex).getStationB().getDisplayName();
        } else if (columnIndex == COL_LINE) {
            return elementManager.getEdgeAt(rowIndex).getLine().getDisplayName();
        } else if (columnIndex == COL_SER) {
            return elementManager.getEdgeAt(rowIndex).getSerialNumber();
        } else if (columnIndex == COL_STR) {
            return elementManager.getEdgeAt(rowIndex).getEdgeStatus();
        } else if (columnIndex == COL_DIS) {
            return elementManager.getEdgeAt(rowIndex).getDistance();
        } else if (columnIndex == COL_TIM) {
            return elementManager.getEdgeAt(rowIndex).getTime();
        } else {
            return "???";
        }
    }
    private NameMap nameMap;
    private ElementManager elementManager;
    private EditCommandManager editCommandManager;
    private String[] columnNames;
    public static final int COL_NUM = 0;
    public static final int COL_STA = 1;
    public static final int COL_STB = 2;
    public static final int COL_LINE = 3;
    public static final int COL_SER = 4;
    public static final int COL_STR = 5;
    public static final int COL_DIS = 6;
    public static final int COL_TIM = 7;
}

class AllEdgeNumCellEditor extends DefaultCellEditor {

    public AllEdgeNumCellEditor(InformationPane infPane) {
        super(new JTextField());
        this.infPane = infPane;
        elementManager = ElementManager.getInstance();
    }

    @Override
    public Object getCellEditorValue() {
        return null;
    }

    @Override
    public Component getTableCellEditorComponent(
            JTable table, Object value, boolean isSelected, int row, int column) {
        try {
            infPane.setFocus(InformationPane.EDGE, elementManager.getEdgeAt(row));
        } catch (InformationPanelException ex) {
            ex.printStackTrace();
        }
        return null;
    }
    private InformationPane infPane;
    private ElementManager elementManager;
}
/**
class EdgeListSelectionListener implements ListSelectionListener {

public EdgeListSelectionListener(InformationPane infPane) {
this.infPane = infPane;
elementManager = ElementManager.getInstance();
}

public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == true) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
int selectedRow = lsm.getMinSelectionIndex();
if (selectedRow != 0) {
infPane.setHighLight(elementManager.getEdgeAt(selectedRow - 1));
infPane.getAllEdgeTablePane().setEdge(elementManager.getEdgeAt(selectedRow - 1));
}
}
}
private InformationPane infPane;
private ElementManager elementManager;
}
 */
